#include "historymessagewidget.h"

#include "Debug.h"

//////////////////////////////////////////////
/// \brief 历史消息内容类
//////////////////////////////////////////////
HistoryMessageItem::HistoryMessageItem(const Message &msg)
{
    this->setStyleSheet("QWidget:hover { background-color: #ECECEC; }"
                        "QLabel { background-color: transparent; color: rgb(178, 178, 178); font-size: 12px; padding: 0,0,2,0;}");

    // 1.网格布局
    QGridLayout* gLayout = new QGridLayout(this);
    gLayout->setContentsMargins(5, 10, 5, 10);
    gLayout->setSpacing(5);

    // 2.1头像
    QPushButton* avatarBtn = new QPushButton();
    avatarBtn->setIcon(msg.m_sender.m_avatar);
    avatarBtn->setFixedSize(34, 34);
    avatarBtn->setIconSize(QSize(34, 34));
    avatarBtn->setCursor(Qt::PointingHandCursor);

    // 2.2昵称+时间
    QLabel* nameLabel = new QLabel(msg.m_sender.m_nickName);
    QLabel* timeLabel = new QLabel(msg.m_time);

    gLayout->addWidget(avatarBtn, 0, 0, 2, 1, Qt::AlignTop);
    gLayout->addWidget(nameLabel, 0, 1, 1, 7, Qt::AlignLeft | Qt::AlignTop);
    gLayout->addWidget(timeLabel, 0, 8, 1, 1, Qt::AlignLeft | Qt::AlignTop);
}

HistoryMessageItem *HistoryMessageItem::makeHistoryMessageItem(const Message &msg)
{
    HistoryMessageItem* item = new HistoryMessageItem(msg);
    item->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);

    QWidget* contentWidget = nullptr;
    if(msg.m_type == model::TEXT_TYPE){
        QLabel* textLabel = new QLabel(msg.m_content);
        textLabel->setWordWrap(true);    // 自动换行
        textLabel->adjustSize();  // 自动调整大小
        textLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
        textLabel->setStyleSheet("QLabel { background-color: transparent; color: black; font-size: 14px; padding: 0,0,2,0;}");
        contentWidget = textLabel;
    }else if(msg.m_type == model::IMAGE_TYPE){
        contentWidget = new ImageButton(msg.m_fileId, msg.m_content);
    }else if(msg.m_type == model::FILE_TYPE){
        contentWidget = new FileLabel(msg.m_fileId, msg.m_fileName);
    }else if(msg.m_type == model::SPEECH_TYPE){
        contentWidget = new SpeechLabel(msg.m_fileId);
    }else{
        LOG() << "历史消息类型错误";
    }
    QGridLayout* gLayout = dynamic_cast<QGridLayout*>(item->layout());
    gLayout->addWidget(contentWidget, 1, 1, 1, 7);
    return item;
}

void HistoryMessageItem::paintEvent(QPaintEvent *)
{
    QStyleOption opt;
    opt.initFrom(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

//////////////////////////////////////////////
/// \brief        历史消息窗口
//////////////////////////////////////////////
HistoryMessageWidget::HistoryMessageWidget(QWidget *parent): QDialog(parent)
{
    this->setFixedSize(500, 400);
    this->setWindowTitle("历史消息");
    this->setWindowIcon(QIcon(":/resource/image/logo.png"));
    this->setAttribute(Qt::WA_DeleteOnClose);
    this->setStyleSheet("QWidget { background-color: white; }"
                        "QScrollArea { border: none; }"
                        "QScrollBar:vertical { width: 2px; background-color: rgb(255, 255, 255); }"
                        "QScrollBar::handle:vertical {background-color: rgb(205, 205, 205);}"
                        "QScrollBar:horizontal { height: 0px;}"
                        "QLineEdit { background-color: rgb(243, 243, 243); border-radius:5px; padding-left: 5px; font-size: 12px;} "
                        "QPushButton { border: none; border-radius: 5px; }"
                        "QPushButton:pressed { background-color: #C6C6C6; }");

    // 1.网格布局
    m_layout = new QGridLayout();
    m_layout->setContentsMargins(10, 0, 10, 0);
    m_layout->setSpacing(5);
    // m_layout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    this->setLayout(m_layout);

    // 2.两个单选框（关键词查询、时间查询）
    m_keySearchBtn = new QRadioButton("按关键词查询");
    m_dateSearchBtn = new QRadioButton("按时间查询");
    m_keySearchBtn->setChecked(true);
    m_layout->addWidget(m_keySearchBtn, 0, 0, 1, 2);
    m_layout->addWidget(m_dateSearchBtn, 0, 2, 1, 2);

    // 3.1搜索框
    m_searchEdit = new QLineEdit();
    m_searchEdit->setPlaceholderText("要搜索的关键字");
    m_searchEdit->setFixedHeight(30);
    m_searchEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    m_layout->addWidget(m_searchEdit, 1, 0, 1, 8);
    // 3.2时间选择
    m_startDateLabel = new QLabel("开始时间");
    m_endDateLabel = new QLabel("结束时间");
    m_startTimeEdit = new QDateTimeEdit(QDateTime::currentDateTime().addDays(-30));
    m_endTimeEdit = new QDateTimeEdit(QDateTime::currentDateTime());
    m_startDateLabel->hide();
    m_endDateLabel->hide();
    m_startTimeEdit->hide();
    m_endTimeEdit->hide();
    // 3.3搜索按钮
    m_searchBtn = new QPushButton();
    m_searchBtn->setIcon(QIcon(":/resource/image/search.png"));
    m_searchBtn->setIconSize(QSize(25, 25));
    m_searchBtn->setFixedSize(30, 30);
    m_layout->addWidget(m_searchBtn, 1, 8, 1, 1);
    // 4.历史消息内容
    initScrollArea();

#if TEST_UI
    QString text = "第三章小结与感悟";
    model::MessageType type = model::MessageType::TEXT_TYPE;
    model::UserInfo sender;
    sender.m_avatar = QIcon(":/resource/image/defaultAvatar2.jpg");
    sender.m_nickName = "left";
    sender.m_phone = "1861234567321";
    Message msg = Message::makeMessage(sender, "", type, text.toUtf8(), "none");
    for (int i = 0; i < 15; ++i) {
        addHistoryMessage(msg);
    }
#endif

    // 绑定槽函数
    RadioBtnsSlots();
}

void HistoryMessageWidget::RadioBtnsSlots()
{
    connect(m_dateSearchBtn, &QRadioButton::clicked, this, [=]{
        m_layout->removeWidget(m_searchEdit);
        m_searchEdit->hide();

        m_layout->addWidget(m_startDateLabel, 1, 0, 1, 1);
        m_layout->addWidget(m_startTimeEdit, 1, 1, 1, 3);
        m_layout->addWidget(m_endDateLabel, 1, 4, 1, 1);
        m_layout->addWidget(m_endTimeEdit, 1, 5, 1, 3);
        m_startDateLabel->show();
        m_startTimeEdit->show();
        m_endDateLabel->show();
        m_endTimeEdit->show();
    });

    connect(m_keySearchBtn, &QRadioButton::clicked, this, [=]{
        m_startDateLabel->hide();
        m_startTimeEdit->hide();
        m_endDateLabel->hide();
        m_endTimeEdit->hide();
        m_layout->removeWidget(m_startDateLabel);
        m_layout->removeWidget(m_startTimeEdit);
        m_layout->removeWidget(m_endDateLabel);
        m_layout->removeWidget(m_endTimeEdit);

        m_layout->addWidget(m_searchEdit, 1, 0, 1, 8);
        m_searchEdit->show();
    });

    auto dataCenter = model::DataCenter::getInstance();
    connect(dataCenter, &model::DataCenter::searchMessageDone, this, &HistoryMessageWidget::clickSearchBtnDone);
    connect(m_searchBtn, &QPushButton::clicked, dataCenter, [=]{
        if(m_keySearchBtn->isChecked()){
            QString searchKey = m_searchEdit->text().trimmed();
            if(searchKey.isEmpty()){
                return;
            }
            dataCenter->searchMessageAsync(searchKey);
        }else{
            auto startTime = m_startTimeEdit->dateTime();
            auto endTime = m_endTimeEdit->dateTime();
            LOG() << "时间区间：" << startTime << "~" << endTime;
            if(startTime > endTime){
                LOG() << "搜索的时间范围不对";
                return ;
            }
            dataCenter->searchMessageByTimeAsync(startTime, endTime);
        }
    });

}

void HistoryMessageWidget::initScrollArea()
{
    QScrollArea* scrollArea = new QScrollArea();
    scrollArea->setWidgetResizable(true);
    scrollArea->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    m_layout->addWidget(scrollArea, 2, 0, 1, 9);

    m_container = new QWidget();
    scrollArea->setWidget(m_container);
    QVBoxLayout* layout = new QVBoxLayout();
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);
    layout->setAlignment(Qt::AlignTop);
    m_container->setLayout(layout);
}

void HistoryMessageWidget::addHistoryMessage(const Message &message)
{
    HistoryMessageItem* item = HistoryMessageItem::makeHistoryMessageItem(message);
    m_container->layout()->addWidget(item);
}

void HistoryMessageWidget::clear()
{
    QVBoxLayout* vlayout = dynamic_cast<QVBoxLayout*>(m_container->layout());
    QLayoutItem* child = nullptr;
    while((child = vlayout->itemAt(0)) != nullptr){
        child->widget()->deleteLater();
        vlayout->removeItem(child);
    }
}

void HistoryMessageWidget::clickSearchBtnDone()
{
    model::DataCenter* dataCenter = model::DataCenter::getInstance();
    auto searchMsgRes = dataCenter->getSearchMessageResult();
    if (searchMsgRes == nullptr) {
        return;
    }
    clear();
    for(const auto& m : *searchMsgRes){
        addHistoryMessage(m);
    }
}


//////////////////////////////////////////////
/// \brief          图片消息
//////////////////////////////////////////////
ImageButton::ImageButton(const QString &fileID, const QByteArray &content)
    :m_fileID(fileID)
{
    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    setStyleSheet("QPushButton { border: none; }");

    if(content.isEmpty()){
        auto dataCenter = model::DataCenter::getInstance();
        connect(dataCenter, &model::DataCenter::getSingleFileDone, this, &ImageButton::updateUI);
        dataCenter->getSingleFileAsync(fileID);
    }else{
        updateUI(fileID, content);
    }
}

void ImageButton::updateUI(const QString &fileID, const QByteArray &content)
{
    if(fileID != m_fileID){
        LOG() << "历史图片消息fileID不匹配，无需变动";
        return ;
    }

    QImage image;
    image.loadFromData(content);

    int width = 0;
    int height = 0;
    if(image.width() > 200){
        width = 200;
        height = ((double)image.height() / image.width()) * width;
    }

    QPixmap pixmap = QPixmap::fromImage(image);
    setIcon(QIcon(pixmap));
    setIconSize(QSize(width, height));
    setFixedSize(width, height);
}

//////////////////////////////////////////////
/// \brief          文件消息
//////////////////////////////////////////////
FileLabel::FileLabel(const QString &fileID, const QString &fileName)
    :m_fileID(fileID), m_fileName(fileName), m_isLoad(false)
{
    setStyleSheet("QLabel { background-color: transparent; color: black; font-size: 14px; padding: 0,0,2,0;}");
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    adjustSize();
    setWordWrap(true);
    setAlignment(Qt::AlignLeft);

    auto dataCenter = model::DataCenter::getInstance();
    connect(dataCenter, &model::DataCenter::getSingleFileDone, this, &FileLabel::updateUI);
    dataCenter->getSingleFileAsync(fileID);

    setText("[文件] " + fileName);
}

void FileLabel::mousePressEvent(QMouseEvent *event)
{
    if(!m_isLoad){
        LOG() << "数据尚未从服务器上加载";
        return;
    }

    QFileInfo fileInfo(m_fileName);
    QString filter = QString("*.%1").arg(fileInfo.suffix());
    QString path = QFileDialog::getSaveFileName(this, "另存为", QDir::homePath(), filter);
    if(path.isEmpty()){
        LOG() << "用户取消打开文件";
        return ;
    }
    model::writeByteArrayToFile(m_content, path);
}

void FileLabel::updateUI(const QString &fileID, const QByteArray &content)
{
    if(fileID != m_fileID){
        LOG() << "历史文件消息fileID不匹配，无需变动";
        return ;
    }

    m_content = content;
    m_isLoad = true;
}

//////////////////////////////////////////////
/// \brief          语音消息
//////////////////////////////////////////////
SpeechLabel::SpeechLabel(const QString &fileID)
    :m_fileID(fileID)
{
    setStyleSheet("QLabel { background-color: transparent; color: black; font-size: 14px; padding: 0,0,2,0;}");
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    setWordWrap(true); // 启⽤⽂本换⾏
    adjustSize(); // 调整⼤⼩以适应内容
    setAlignment(Qt::AlignTop | Qt::AlignLeft);
    setText("[语音]");

    // 二次请求进行数据传输
    auto dataCenter = model::DataCenter::getInstance();
    connect(dataCenter, &model::DataCenter::getSingleFileDone, this, &SpeechLabel::updateUI);
    dataCenter->getSingleFileAsync(fileID);
}

void SpeechLabel::updateUI(const QString &fileID, const QByteArray &content)
{
    if(fileID != m_fileID){
        LOG() << "历史语音消息fileID不匹配，无需变动";
        return ;
    }
    m_content = content;
    m_isLoad = true;
}

void SpeechLabel::mousePressEvent(QMouseEvent *event)
{
    if(!m_isLoad){
        LOG() << "数据尚未从服务器上加载";
        return;
    }

    // 1.更改状态
    setText("播放中...");

    // 2.播放语音
    auto sound = SoundRecorder::getInstance();
    connect(sound, &SoundRecorder::soundPlayDone, this, [=]{
        if(this->text() == "播放中..."){
            setText("[语音]");
        }
    });
    sound->startPlay(m_content);
}
